import sys
import hashlib
import os
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QTextEdit, QListWidget, QMessageBox, QDialog, QFormLayout
from cryptography.hazmat.primitives.ciphers import Cipher, modes
from cryptography.hazmat.primitives.ciphers.algorithms import AES
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

# Mock password data
password_data = [
    {"name": "Example", "url": "http://example.com", "username": "user1", "password": "password1"},
    {"name": "Test", "url": "http://test.com", "username": "user2", "password": "password2"},
    # Add more password entries as needed
]

class PasswordManager(QMainWindow):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.setWindowTitle("Password Manager")
        self.setGeometry(100, 100, 800, 600)

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.layout = QVBoxLayout()
        self.central_widget.setLayout(self.layout)

        # Widgets for main password input
        self.password_label = QLabel("Enter Master Password:")
        self.password_input = QLineEdit()
        self.password_input.setEchoMode(QLineEdit.Password)
        self.password_submit = QPushButton("Submit")

        self.password_submit.clicked.connect(self.check_password)

        self.layout.addWidget(self.password_label)
        self.layout.addWidget(self.password_input)
        self.layout.addWidget(self.password_submit)

    def check_password(self):
        password = self.password_input.text()
        hashed_password = hashlib.sha256(password.encode()).hexdigest()

        if os.path.exists("master_password.txt"):
            with open("master_password.txt", "r") as f:
                saved_password = f.read().strip()

                if hashed_password == saved_password:
                    self.main_interface()
                else:
                    QMessageBox.warning(self, "Warning", "Incorrect master password!")
        else:
            reply = QMessageBox.question(self, "Register", "No master password found. Do you want to register a new one?", 
                                            QMessageBox.Yes | QMessageBox.No)

            if reply == QMessageBox.Yes:
                with open("master_password.txt", "w") as f:
                    f.write(hashed_password)
                QMessageBox.information(self, "Success", "Master password registered successfully!")
            else:
                self.password_input.clear()

    def main_interface(self):
        # Clear existing layout
        if self.central_widget.layout() is not None:
            self.clear_layout(self.central_widget.layout())

        # Add widgets for the main interface
        self.password_list_label = QLabel("Password List:")
        self.password_list = QListWidget()
        self.add_password_button = QPushButton("Add Password")
        self.add_password_button.clicked.connect(self.add_password_dialog)
        self.search_label = QLabel("Search:")
        self.search_input = QLineEdit()
        self.search_input.setPlaceholderText("Enter name, URL, etc.")
        self.search_input.textChanged.connect(self.search_password)

        # Add widgets to the existing layout
        self.layout.addWidget(self.password_list_label)
        self.layout.addWidget(self.password_list)
        self.layout.addWidget(self.add_password_button)
        self.layout.addWidget(self.search_label)
        self.layout.addWidget(self.search_input)


    def add_password_dialog(self):
        dialog = AddPasswordDialog()
        if dialog.exec_() == QDialog.Accepted:
            password_info = dialog.get_password_info()
            # Add password logic here
            print(password_info)  # Placeholder for actual logic

    def search_password(self):
        keyword = self.search_input.text().lower()
        self.password_list.clear()

        # Assuming password_data is a list of dictionaries, each containing password information
        for password in password_data:
            if any(keyword in value.lower() for value in password.values()):
                item = "{} - {}".format(password['name'], password['url'])
                self.password_list.addItem(item)

    def clear_layout(self, layout):
        while layout.count():
            item = layout.takeAt(0)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            else:
                sub_layout = item.layout()
                if sub_layout is not None:
                    self.clear_layout(sub_layout)

class AddPasswordDialog(QDialog):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Add Password")
        self.layout = QVBoxLayout()

        # Create form layout for input fields
        self.form_layout = QFormLayout()

        # Input fields
        self.name_input = QLineEdit()
        self.url_input = QLineEdit()
        self.username_input = QLineEdit()
        self.password_input = QLineEdit()

        # Set password input field echo mode to Password
        self.password_input.setEchoMode(QLineEdit.Password)

        # Add input fields to form layout
        self.form_layout.addRow("Name:", self.name_input)
        self.form_layout.addRow("URL:", self.url_input)
        self.form_layout.addRow("Username:", self.username_input)
        self.form_layout.addRow("Password:", self.password_input)

        # Add form layout to main layout
        self.layout.addLayout(self.form_layout)

        # Add submit button
        self.submit_button = QPushButton("Submit")
        self.submit_button.clicked.connect(self.accept)
        self.layout.addWidget(self.submit_button)

        # Set main layout for the dialog
        self.setLayout(self.layout)

    def get_password_info(self):
        name = self.name_input.text()
        url = self.url_input.text()
        username = self.username_input.text()
        password = self.password_input.text()
        return {'name': name, 'url': url, 'username': username, 'password': password}

def encrypt_and_save_password(password):
    # 生成随机盐
    salt = os.urandom(16)

    # 使用PBKDF2派生密钥
    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=salt,
        iterations=100000,  # 可根据需要调整迭代次数
        backend=default_backend()
    )
    key = kdf.derive(password.encode())

    # 生成随机初始化向量（IV）
    iv = os.urandom(16)

    # 加密密码
    cipher = Cipher(AES(key), modes.CFB(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    ciphertext = encryptor.update(password.encode()) + encryptor.finalize()

    # 将加密后的密码、密钥、IV和盐保存到文件中
    with open("password.bin", "wb") as f:
        f.write(salt)
        f.write(iv)
        f.write(ciphertext)

    return key

def decrypt_password(key):
    with open("password.txt", "rb") as f:
        key_read = f.read(16)  # 读取密钥
        nonce = f.read(16)     # 读取 nonce
        tag = f.read(16)       # 读取 tag
        ciphertext = f.read()  # 读取加密后的密码

    cipher = AES.new(key_read, AES.MODE_EAX, nonce=nonce)
    decrypted_password = cipher.decrypt(ciphertext)
    try:
        cipher.verify(tag)
        return decrypted_password.decode()
    except ValueError:
        return None

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = PasswordManager()
    window.show()
    sys.exit(app.exec_())
